第一步先搞清楚兩件事:
Node.js 是 單執行緒(single-threaded) 的,但它能同時處理很多事情,靠的就是 Event Loop。
可以想像 Node.js 的工作流程:
今天我用 setTimeout、setImmediate、process.nextTick 來感受一下 Event Loop 的順序。
console.log("開始");
setTimeout(() => {
  console.log("setTimeout");
}, 0);
setImmediate(() => {
  console.log("setImmediate");
});
process.nextTick(() => {
  console.log("process.nextTick");
});
console.log("結束");
執行結果通常會是:
開始
結束
process.nextTick
setTimeout
setImmediate
解釋:
process.nextTick:會在目前這個階段結束後「馬上」執行(比 setTimeout 還快)setTimeout(fn, 0):丟到 Event Loop 的 timer 階段,等到主程式跑完才執行setImmediate:等到 check 階段 才跑,通常比 setTimeout 晚這個順序一開始很難記,但實際跑過一次就會有感覺。
寫 Node.js 不可能把所有程式都塞在同一支檔案,所以必須要學會「模組化」。
utils.js
function add(a, b) {
  return a + b;
}
module.exports = { add };
index.js
const { add } = require("./utils");
console.log(add(2, 3)); // 5
utils.js
export function add(a, b) {
  return a + b;
}
index.js
import { add } from "./utils.js";
console.log(add(2, 3)); // 5
注意:ESM 在 Node.js 要記得設定 "type": "module"(放在 package.json 裡)。
今天的實作我分成兩部分:
跑一遍 setTimeout、setImmediate、process.nextTick,感受它們執行順序的差別。
math.js:裡面 export 一個 add 函式app.js:import 這個函式,拿來做簡單運算這樣就能清楚體會模組拆分的好處:檔案更乾淨、功能更獨立。
今天最有感的有兩點:
process.nextTick 比 setTimeout 還要快。require 和 import 都能拆檔案,但新的專案還是建議用 ESM(import/export),語法比較直覺。整體來說,今天算是 Node.js 的暖身。